﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Management;
using System.Net.NetworkInformation;
using System.Net.Sockets;


/***
*	Title：获取硬件信息
*		类：硬件信息类【核心层】
*	Description：
*		功能：
*	    《1》获取硬件的编号（注意：不能够保证能够获取到所有的硬件信息编号）
*		    1、获取到CPU编号
*		    2、获取到主板编号
*		    3、获取到硬盘编号
*		    4、获取到BIOS编号
*		    5、获取网卡地址
*		《2》获取到电脑其他信息（（注意：不能够保证能够获取到所有的硬件信息）
*		    1、获取到系统名称
*		    2、获取到CPU的名称
*		    3、获取到当前CPU的核心数量
*		    4、获取到系统的内存（GB）
*		    5、获取到硬盘的存储空间(总空间、剩余空间(GB))
*		    6、获取到屏幕分辩率
*		    7、获取到GPU的名称
*		    8、获取到GPU的显存大小(单位：GB)
*		    
*	时间：2021.11.16
*	版本：1.0
*	作者：李勇
*	变更描述：创建
*/


namespace HardwareInfo
{
    public static class HardwareInfoHelper
    {

        #region 基础参数

        //CPU的参数
        private const string _CPUPara = "Win32_Processor";
        private const string _CPUIDPara = "ProcessorId";

        //主板参数
        private const string _MainBoardPara = "Win32_BaseBoard";
        private const string _MainBoardIDPara = "SerialNumber";

        //硬盘参数
        private const string _HardDiskPara = "Win32_PhysicalMedia";
        private const string _HardDiskIDPara = "SerialNumber";

        //BIOS参数
        private const string _BiosPara = "Win32_BIOS";
        private const string _BiosIDPara = "SerialNumber";

        //系统名称
        private const string _SystemNamePara = "Win32_OperatingSystem";
        private const string _SystemName = "Name";

        //CPU名称
        private const string _CPUName = "Name";
        private const string _CPUAllPara = "Select * from Win32_Processor";
        private const string _CPUCoreNum = "NumberOfCores";

        #endregion

        /// <summary>
        /// 获取CPUID
        /// </summary>
        /// <returns>CPUID</returns>
        public static string GetCpuID()
        {
            string id = string.Empty;
            ManagementClass mcCpu = new ManagementClass(_CPUPara);
            ManagementObjectCollection mocCpu = mcCpu.GetInstances();
            foreach (ManagementObject m in mocCpu)
            {
                id = m[_CPUIDPara].ToString().Trim();//BFEBFBFF00000F65
                break;
            }
            return id;
        }

        /// <summary>
        /// 获取主板ID
        /// </summary>
        /// <returns>主板ID</returns>
        public static string GetMainBoardID()
        {
            string strID = null;
            ManagementClass mc = new ManagementClass(_MainBoardPara);
            ManagementObjectCollection moc = mc.GetInstances();

            foreach (ManagementObject mo in moc)
            {
                strID = mo.Properties[_MainBoardIDPara].Value.ToString().Trim();
                break;
            }

            return strID;
        }

        /// <summary>
        /// 获取BOISID
        /// </summary>
        /// <returns>BOISID</returns>
        public static string GetBiosID()
        {
            string strID = null;
            ManagementClass mc = new ManagementClass(_BiosPara);
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                strID = mo.Properties[_BiosIDPara].Value.ToString().Trim();                
                break;
            }
            return strID;
        }

        /// <summary>
        /// 获取硬盘ID
        /// </summary>
        /// <returns>硬盘id</returns>
        public static string GetHardDiskID()
        {
            string strID = null;

            ManagementClass mc = new ManagementClass(_HardDiskPara);
            ManagementObjectCollection moc = mc.GetInstances();

            foreach (ManagementObject mo in moc)
            {
                strID = mo.Properties[_HardDiskIDPara].Value.ToString().Trim();
                break;
            }
            return strID;

        }

        /// <summary>
        /// 获取物理网卡的MAC地址
        /// </summary>
        /// <returns>MAC地址</returns>
        public static string GetLocaNetWorkMAC()
        {
            string MAC=string.Empty;
            var nwtWorkInfos = GetNetworkInterfaceMessage();
            foreach (var item in nwtWorkInfos)
            {
                if (item.NetWordCardType=="物理网卡")
                {
                    MAC = item.MAC;
                    break;
                }
            }
            return MAC;
        }

        /// <summary>
        /// 获取无线网卡MAC地址
        /// </summary>
        /// <returns>MAC地址</returns>
        public static string GetWLANNetWorkMAC()
        {
            string MAC = string.Empty;
            var nwtWorkInfos = GetNetworkInterfaceMessage();
            foreach (var item in nwtWorkInfos)
            {
                if (item.NetWordCardType == "无线网卡")
                {
                    MAC = item.MAC;
                    break;
                }
            }
            return MAC;
        }

        /// <summary>
        /// 获取所有网卡MAC
        /// </summary>
        /// <returns></returns>
        static string[] GetALLNetWorkMAC()
        {
            List<string> macs = new List<string>();
            string MoAddress = string.Empty;
            ManagementClass networkAdapter = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection adapterC = networkAdapter.GetInstances();
            foreach (ManagementObject m in adapterC)
            {
                if ((bool)m["IPEnabled"] == true)
                {
                    MoAddress = m["MacAddress"].ToString().Trim();
                    //MoAddress = MoAddress.Replace(':', '-');
                    macs.Add(MoAddress);
                    m.Dispose();
                }
            }
            return macs.ToArray();
        }

        #region 获取设备所有网络信息

        /// <summary>
        /// 获取所有网络连接的信息
        /// </summary>
        /// <returns></returns>
        static List<NetWorkCardInfo> GetNetworkInterfaceMessage()
        {
            List<NetWorkCardInfo> netWorkCardInfos = new List<NetWorkCardInfo>();

            NetworkInterface[] fNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in fNetworkInterfaces)
            {
                #region " 网卡类型 "   

                string fCardType = "未知网卡";
                string fRegistryKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + adapter.Id + "\\Connection";
                RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false);
                if (rk != null)
                {
                    // 区分 PnpInstanceID    
                    // 如果前面有 PCI 就是本机的真实网卡   
                    // MediaSubType 为 01 则是常见网卡，02为无线网卡。   
                    string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString();
                    int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0));
                    if (fPnpInstanceID.Length > 3 &&
                        fPnpInstanceID.Substring(0, 3) == "PCI")
                        fCardType = "物理网卡";
                    else if (fMediaSubType == 1)
                        fCardType = "虚拟网卡";
                    else if (fMediaSubType == 2)
                        fCardType = "无线网卡";
                }

                #endregion

                #region " 网卡信息 " 

                NetWorkCardInfo n = new NetWorkCardInfo
                {
                    NetWordCardType=fCardType,
                    Id = adapter.Id,
                    Name = adapter.Name,
                    Description = adapter.Description,
                    NetworkInterfaceType = adapter.NetworkInterfaceType.ToString(),
                    MAC = adapter.GetPhysicalAddress().ToString(),

                };               

                /*Console.WriteLine("-----------------------------------------------------------");
                Console.WriteLine("-- " + fCardType);
                Console.WriteLine("-----------------------------------------------------------");
                Console.WriteLine("Id .................. : {0}", adapter.Id);  // 获取网络适配器的标识符   
                Console.WriteLine("Name ................ : {0}", adapter.Name);  // 获取网络适配器的名称   
                Console.WriteLine("Description ......... : {0}", adapter.Description);  // 获取接口的描述   
                Console.WriteLine("Interface type ...... : {0}", adapter.NetworkInterfaceType);  // 获取接口类型   
                Console.WriteLine("Is receive only...... : {0}", adapter.IsReceiveOnly);  // 获取 Boolean 值，该值指示网络接口是否设置为仅接收数据包。   
                Console.WriteLine("Multicast............ : {0}", adapter.SupportsMulticast);  // 获取 Boolean 值，该值指示是否启用网络接口以接收多路广播数据包。   
                Console.WriteLine("Speed ............... : {0}", adapter.Speed);  // 网络接口的速度   
                Console.WriteLine("Physical Address .... : {0}", adapter.GetPhysicalAddress().ToString());  // MAC 地址   */
                IPInterfaceProperties fIPInterfaceProperties = adapter.GetIPProperties();
                UnicastIPAddressInformationCollection UnicastIPAddressInformationCollection = fIPInterfaceProperties.UnicastAddresses;
                foreach (UnicastIPAddressInformation UnicastIPAddressInformation in UnicastIPAddressInformationCollection)
                {
                    if (UnicastIPAddressInformation.Address.AddressFamily == AddressFamily.InterNetwork)
                        //Console.WriteLine("Ip Address .......... : {0}", UnicastIPAddressInformation.Address);  // Ip 地址   
                        n.IPAddress = UnicastIPAddressInformation.Address.ToString();
                }
                netWorkCardInfos.Add(n);
                #endregion
            }
            return netWorkCardInfos;
        }

        #endregion

        #region   1-获取到电脑其他信息

        /// <summary>
        /// 获取到系统名称
        /// </summary>
        /// <returns>返回当前电脑系统的名称</returns>
        public static string GetSystemName()
        {
            string str = null;

            ManagementClass manag = new ManagementClass(_SystemNamePara);
            ManagementObjectCollection managCollection = manag.GetInstances();
            foreach (ManagementObject m in managCollection)
            {
                str = m[_SystemName].ToString();
                break;
            }

            return str;
        }

        /// <summary>
        /// 获取到CPU的名称
        /// </summary>
        /// <returns>返回当前电脑CPU的名称</returns>
        public static string GetCPUName()
        {
            string str = null;
            ManagementClass mcCPU = new ManagementClass(_CPUPara);
            ManagementObjectCollection mocCPU = mcCPU.GetInstances();
            foreach (ManagementObject m in mocCPU)
            {
                str = m[_CPUName].ToString();
                break;
            }

            return str;
        }

        /// <summary>
        /// 获取到当前CPU的核心数量
        /// </summary>
        /// <returns>返回当前电脑CPU的核心数量</returns>
        public static int GetCPUNumber()
        {
            int coreCount = 0;

            foreach (var item in new ManagementObjectSearcher(_CPUAllPara).Get())
            {
                coreCount += int.Parse(item[_CPUCoreNum].ToString());
            }

            return coreCount;
        }

        /// <summary>
        /// 获取到系统的内存(GB)
        /// </summary>
        /// <returns>返回当前电脑内存的大小</returns>
        public static float GetSystemMemorySizeOfGB()
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher();   //用于查询一些如系统信息的管理对象
            searcher.Query = new SelectQuery("Win32_PhysicalMemory", "", new string[] { "Capacity" });//设置查询条件
            ManagementObjectCollection collection = searcher.Get();   //获取内存容量 
            ManagementObjectCollection.ManagementObjectEnumerator em = collection.GetEnumerator();
            long capacity = 0;
            while (em.MoveNext())
            {
                ManagementBaseObject baseObj = em.Current;
                if (baseObj.Properties["Capacity"].Value != null)
                {
                    capacity += long.Parse(baseObj.Properties["Capacity"].Value.ToString());
                }
            }
            float size = capacity / 1024 / 1024 / 1024;
            return size;
        }

        /// <summary>
        /// 获取到硬盘的存储空间(总空间、剩余空间(GB))
        /// </summary>
        /// <returns>返回当前电脑的硬盘存储空间</returns>
        public static float[] GetHardDiskSpace()
        {
            float[] Space = new float[2];
            System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();
            long totalFreeSpace = 0;
            long totalDiskSize = 0;
            foreach (var drive in drives)
            {
                if (drive.IsReady)  //判断代码运行时 磁盘是可操作作态 
                {
                    totalFreeSpace += drive.AvailableFreeSpace;
                    totalDiskSize += drive.TotalSize;
                }
            }

            //总空间(单位：GB)
            float totalSpace = totalDiskSize / 1024 / 1024 / 1024;
            //剩余空间(单位:GB)
            float surplusSpce = totalFreeSpace / 1024 / 1024 / 1024;

            Space[0] = totalSpace;
            Space[1] = surplusSpce;

            return Space;

        }

        /// <summary>
        /// 获取到GPU的名称
        /// </summary>
        /// <returns>返回当前电脑的GPU名称</returns>
        public static string GetGPUName()
        {
            string str = null;
            ManagementClass manage = new ManagementClass("Win32_VideoController");
            ManagementObjectCollection manageCollection = manage.GetInstances();
            foreach (ManagementObject m in manageCollection)
            {
                str = m["VideoProcessor"].ToString().Replace("Family", "");
                break;
            }

            return str;
        }

        /// <summary>
        ///获取到GPU的显存大小(单位：GB)
        /// </summary>
        /// <returns>返回当前电脑的GPU显存大小</returns>
        public static float GetGPUMemorySize()
        {
            float size = 0;
            ManagementClass manage = new ManagementClass("Win32_VideoController");
            ManagementObjectCollection manageCollection = manage.GetInstances();
            foreach (ManagementObject m in manageCollection)
            {
                size = (Convert.ToInt64(m["AdapterRAM"]) / 1024 / 1024 / 1024);
                break;
            }

            return size;
        }

        #endregion

    }

    #region 网卡信息
    class NetWorkCardInfo
    {
        /// <summary>
        /// 网络适配器类型
        /// </summary>
        public string NetWordCardType { get; set; }
        /// <summary>
        /// 网络适配器标识符
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// 网络适配器的名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 网络适配器的描述
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 网络接口描述
        /// </summary>
        public string NetworkInterfaceType { get; set; }

        /// <summary>
        /// 网络适配器的MAC地址
        /// </summary>
        public string MAC { get; set; }

        /// <summary>
        /// 网络适配器的IP地址
        /// </summary>
        public string IPAddress { get; set; }

    }
    #endregion
}
